/*
	Ruler.java
	
	2007/06/07  WHF  Created from Rule.java, part of Sun's ScrollPane tutorial.
	2007/07/16  WHF  Made more general.
*/

package org.javamap;

import java.awt.*;
import javax.swing.*;

class Ruler extends JComponent implements SwingConstants
{
    public static final int SIZE = 35;

    public Ruler(int o, JComponent comp) {
        orientation = o;
		this.comp = comp;
		
		setBackground(new Color(230, 163, 4));
		setFont(new Font("SansSerif", Font.PLAIN, 10));
		//int PIXELSPERINCH = Toolkit.getDefaultToolkit().getScreenResolution();
        //setIncrementAndUnits(PIXELSPERINCH/2, PIXELSPERINCH, "in");
		setIncrement(1.0);
		setLength(10.0, "in");
    }

	/**
	  * @param increment      pixels between ticks
	  * @param pixelsPerUnit  number of pixels per map scale
	  * @param unitName       name of unit for display purposes.
	  */
/*    public void setIncrementAndUnits(
			int increment,
			int pixelsPerUnit,
			String unitName) {				
		this.increment = increment;
		this.pixelsPerUnit = pixelsPerUnit;
		this.unitName = unitName;
		repaint();
    } */

    public double getIncrement() {
        return increment;
    }
	
	/**
	  * @param increment  Space between ticks in engineering units.
	  */
	public void setIncrement(double increment)
	{
		this.increment = increment;
	}		
	
	public void setStart(int start) { startPixel = start; }
	/**
	  * Set the end of the measured space, in client pixels.  An end of -1
	  *  represents "to the end of the client".
	  */
	public void setEnd(int end) { endPixel = end; }

	/**
	  * @param length     the size of the rulered item in engineering units	
	  * @param unitName   name of the unit for display purposes.
	  */
	public void setLength(double length, String unitName)
	{
		this.length = length;
		this.unitName = unitName;
	}

	public Dimension getPreferredSize()
	{
		Dimension d = comp.getPreferredSize(); // a copy
		
		if (orientation == VERTICAL) d.width = SIZE;
		else d.height = SIZE;
		
		return d;
	}

    protected void paintComponent(Graphics g) {
		Rectangle drawHere = g.getClipBounds();
		//Rectangle drawHere = new Rectangle(getSize());

        // Fill clipping area with dirty brown/orange.
        g.setColor(getBackground()); // is necessary
        g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);

        // Do the ruler labels in a small font that's black.
        //g.setFont(getFont()); not necessary, set for component
        g.setColor(Color.black);
		
		int clipStart, clipEnd;
		if (orientation == HORIZONTAL) {
			clipStart = drawHere.x;
			clipEnd = drawHere.x + drawHere.width;
		} else { 
			clipStart = drawHere.y;
			clipEnd = drawHere.y + drawHere.height;
		}
		
		int width;
		if (endPixel == -1) width = getSize().width - startPixel;
		else width = endPixel - startPixel;
		
		int maxI = (int) (Math.round(length / increment));
		int startI = (int) 
				((clipStart - startPixel) * length / width / increment);
		if (startI < 0) startI = 0;
		int endI = (int) 
				((clipEnd - startPixel)	* length / width / increment);				
		if (endI > maxI) endI = maxI;
		
		for (int ii = startI; ii <= endI; ++ii) {
			int tickLength = 10;
			double x = increment * ii;
			int p = ((int) Math.floor(width * x / length)) + startPixel;
			String text = Long.toString(Math.round(x));
			
			if (orientation == HORIZONTAL) {
				g.drawLine(p, SIZE-1, p, SIZE-tickLength-1);
				if (text != null)
					g.drawString(text, p-3, 21);
			} else {
				g.drawLine(SIZE-1, p, SIZE-tickLength-1, p);
				if (text != null)
					g.drawString(text, 10, p-3);
			}
		}
		Rectangle visRect = getVisibleRect();
		if (orientation == HORIZONTAL)
			g.drawString(unitName, visRect.x + visRect.width / 2, 9);
		else {
			g.setFont(g.getFont().deriveFont(
					java.awt.geom.AffineTransform.getRotateInstance(-Math.PI/2)
			));
			g.drawString(unitName, 8, visRect.y + visRect.height / 2);
		}
    }

//*****************************  Data Members  ******************************//	
    private int orientation;
	private double increment, length;
	private int startPixel = 0, endPixel = -1;
	private String unitName;
	private JComponent comp;

}
